﻿using Net.Distributed;
using Cysharp.Threading.Tasks;

namespace WordGames.System
{
    public class Cluster
    {
        public string Name { get; internal set; }
        private readonly List<TcpNetwork> clients = new();
        private readonly Dictionary<string, TcpNetwork> connects = new();
        private readonly ConsistentHashing<TcpNetwork> consistentHashing = new();
        private int roundRobinCount;

        public async UniTask<TcpNetwork> GetConnect(string host, string node = null)
        {
            TcpNetwork client;
            lock (this)
            {
                if (connects.TryGetValue(host, out client))
                    return client;
                client = ClusterSystem.CreateClient();
                var parts = host.Split(':');
                client.Ip = parts[0];
                client.Port = int.Parse(parts[1]);
                connects.Add(host, client);
                clients.Add(client);
                if (!string.IsNullOrEmpty(node))
                    consistentHashing.AddNode(node, client);
            }
            await client.Connect();
            return client;
        }

        public void Multicast(Enum protocol, params object[] pars)
        {
            for (int i = 0; i < clients.Count; i++)
            {
                clients[i].Call(protocol, pars);
            }
        }

        public TcpNetwork GetRoundRobin()
        {
            return clients[roundRobinCount++ % clients.Count];
        }

        public TcpNetwork GetHashing(string key)
        {
            return consistentHashing.GetNode(key).Token;
        }

        public override string ToString()
        {
            return $"{Name}";
        }
    }
}